<?php
class AppconfigHandler {
	public static function upgradeDatabase() {
		try {
			// -1 = Unknown SQL error.
			$oGood = AppconfigHandler::getGoodDatabase();
			$oCurrent = AppconfigHandler::getCurrentDatabase();

			function mkFieldString($sFieldname, $oField) {
				$sFieldString = $sFieldname.' '.$oField['type'];
				if ($oField['primary_key']) {
					$sFieldString .= ' PRIMARY KEY AUTO_INCREMENT';
				}
				if (!$oField['null']) {
					$sFieldString .= ' NOT NULL';
				}
				if ($oField['default'] || $oField['default'] == 0) { // We also want to catch (int)0 and (string)'0'.
					$sFieldString .= ' DEFAULT \''.$oField['default'].'\'';
				}
				if ($oField['extra']) {
					$sFieldString .= ' '.$oField['extra'];
				}
				return $sFieldString;
			}

			foreach ($oGood as $sTablename => $oGoodTable) {
				if (is_array($oCurrent[$sTablename])) {
					foreach ($oGoodTable as $sFieldname => $oGoodField) {
						if (is_array($oCurrent[$sTablename][$sFieldname])) {
							if ($oGoodField != $oCurrent[$sTablename][$sFieldname]) {
								$sQueryString = 'ALTER TABLE '.$sTablename.' CHANGE '.$sFieldname.' '.mkFieldString($sFieldname, $oGoodField);
								DataHandler::query($sQueryString);
							}
						}
						else {
							$sQueryString = 'ALTER TABLE '.$sTablename.' ADD '.mkFieldString($sFieldname, $oGoodField);
							DataHandler::query($sQueryString);
						}
					}

					foreach ($oCurrent[$sTablename] as $sFieldname => $oField) {
						if (!is_array($oGoodTable[$sFieldname ])) {
							$sQueryString = 'ALTER TABLE '.$sTablename.' DROP '.$sFieldname;
							DataHandler::query($sQueryString);
						}
					}
				}
				else {
					$sQueryString = 'CREATE TABLE '.$sTablename.' (';
					$bFirst = true;
					foreach ($oGoodTable as $sFieldname => $oField) {
						if (!$bFirst) {
							$sQueryString .= ', ';
						}
						$sQueryString .= mkFieldString($sFieldname, $oField);
						$bFirst = false;
					}
					$sQueryString .= ')';
					DataHandler::query($sQueryString);
				}
			}

			return true;
		}
		catch (Exception $e) {
			ErrorHandler::addError($e->getMessage());
		}
	}

	public static function getCurrentDatabase() {
		try {
			$oDatabase = array();
			$oQuery = DataHandler::query("SHOW TABLES");
			
			while (list($sTablename) = $oQuery->fetch(PDO::FETCH_NUM)) {
				$oDatabase[$sTablename] = array();
				$oTableQuery = DataHandler::query("SHOW COLUMNS FROM ?", $sTablename);

				while ($oRow = $oTableQuery->fetch(PDO::ASSOC)) {
					$oDatabase[$sTablename][$oRow['Field']] = array(
						'type' => $oRow['Type'],
						'null' => ($oRow['Null'] == 'YES'),
						'primary_key' => ($oRow['Key'] == 'PRI'),
						'default' => $oRow['Default'],
						'extra' => $oRow['Extra']
					);
				}
			}
			return $oDatabase;
		}
		catch (Exception $e) {
			ErrorHandler::addError($e->getMessage());
		}
	}
	
	public static function getGoodDatabase() {
		try {
			require('setup/mijob-'.cAppVersion.'.mijobdb');
			return $oDatabase;
		}
		catch (Exception $e) {
			ErrorHandler::addError($e->getMessage());
		}
	}
	
	public static function translate($oTranslation) {
		try {
			foreach ($oTranslation as $sView => $sStrings) {
				if ($sView == 'system') {
					$sFilename = 'include/lang/'.$_SESSION['oUserVars']['language'].'.lang.php';
				}
				else {
					list($sClass, $sBox) = split('-', $sView);
					$sFilename = 'include/classes/'.$sClass.'/lang/'.$_SESSION['oUserVars']['language'].'/'.$sClass.'.'.$sBox.'.lang.php';
				}

				$sLang = array();
				$sOldLang = array();
				if (is_file($sFilename)) {
					if (!is_writable($sFilename)) {
						return -1;
					}
					require($sFilename);
					$sOldLang = $sLang;
				}
				else {
					if (!is_writable(dirname($sFilename))) {
						return -1;
					}
					touch($sFilename);
				}

				$sNewLang = array_merge($sStrings, $sOldLang);
				$oFile = fopen($sFilename, 'w');
				fwrite($oFile, "<?php\n");
				fwrite($oFile, "\$sLang = array(\n");
				foreach ($sNewLang as $sEnglish => $sTranslation) {
					$sEnglish = str_replace('\'', '\\\'', stripslashes($sEnglish));
					$sTranslation = str_replace('\'', '\\\'', stripslashes($sTranslation));
					if (!$sEnglish || !$sTranslation) {
						continue;
					}
					fwrite($oFile, "\t'".$sEnglish."' => '".$sTranslation."',\n");
				}
				fwrite($oFile, ");\n");
				fwrite($oFile, "?>\n");
				fclose($oFile);
			}
			return true;
		}
		catch (Exception $e) {
			ErrorHandler::addError($e->getMessage());
		}
	}
	
	public static function getLanguages() {
		$sLanguage = array(
			'en' => 'English',
			//'dk' => 'Danish / Dansk',
			//'fi' => 'Finnish / Suomea',
			//'fr' => 'French',
			//'de' => 'German / Deutsch',
			'is' => 'Icelandic / �slenska',
			//'it' => 'Italian',
			//'no' => 'Norwegian',
			//'sp' => 'Spanish',
			//'se' => 'Swedish / Svenska',
			//'tr' => 'Turkish',
		);
		return $sLanguage;
	}
	
	public static function setup($sRootUser, $sRootPass, $sDataHost, $sDataUser, $sDataPass, $sDataPassAgain, $sDataBase, $bUseExisting, $sUser, $sPass, $sPassAgain, $sFullname, $sEmail) {
		try {
			if (!$sUser) {
				throw new MiJobException('Missing username');
			}

			if ($bUseExisting) {
				DataHandler::connect($sDataHost, $sDataBase, $sDataUser, $sDataPass);

				$bDatabaseInserted = AppconfigHandler::insertDatabase($sDataHost, $sDataBase, $sDataUser, $sDataPass);

				$oFile = fopen('include/dblogin.inc.php', 'w');
				fwrite($oFile, "<?php\n");
				fwrite($oFile, "define('DATA_HOST', '".$sDataHost."');\n");
				fwrite($oFile, "define('DATA_USER', '".$sDataUser."');\n");
				fwrite($oFile, "define('DATA_PASS', '".$sDataPass."');\n");
				fwrite($oFile, "define('DATA_BASE', '".$sDataBase."');\n");
				fwrite($oFile, "define('DATA_USERBASE', '".$sDataBase."');\n");
				fwrite($oFile, "?>\n");
				fclose($oFile);

				DataHandler::query("
					INSERT INTO users (
						user,
						pass,
						name,
						email,
						level
					) VALUES (
						?,
						PASSWORD(?),
						?,
						?,
						?
					)
				", $sUser, $sPass, $sFullname, $sEmail, 'admin');
			}
			else {
				DataHandler::connect($sDataHost, '', $sRootUser, $sRootPass);

				$oDataListQuery = DataHandler::query("SHOW DATABASES");
				$bDatabaseExists = false;
				while (list($sFoundDatabase) = $oDataListQuery->fetch(PDO::FETCH_NUM)) {
					if ($sFoundDatabase == $sDataBase) {
						$bDatabaseExists = true;
						break;
					}
				}

				if ($bDatabaseExists) {
					throw new Exception('Database already exists');
				}

				DataHandler::query('CREATE DATABASE '.$sDataBase);

				DataHandler::query("
					GRANT ALL ON $sDataBase.*
					TO '$sDataUser'@'$sDataHost'
					IDENTIFIED BY '$sDataPass'
				");

				$bDatabaseInserted = AppconfigHandler::insertDatabase($sDataHost, $sDataBase, $sDataUser, $sDataPass);

				$oFile = fopen('include/dblogin.inc.php', 'w');
				fwrite($oFile, "<?php\n");
				fwrite($oFile, "define('DATA_HOST', '".$sDataHost."');\n");
				fwrite($oFile, "define('DATA_USER', '".$sDataUser."');\n");
				fwrite($oFile, "define('DATA_PASS', '".$sDataPass."');\n");
				fwrite($oFile, "define('DATA_BASE', '".$sDataBase."');\n");
				fwrite($oFile, "define('DATA_USERBASE', '".$sDataBase."');\n");
				fwrite($oFile, "?>\n");
				fclose($oFile);

				DataHandler::query("
					INSERT INTO users (
						user,
						pass,
						name,
						email,
						level
					) VALUES (
						?,
						PASSWORD(?),
						?,
						?,
						?
					)
				", $sUser, $sPass, $sFullname, $sEmail, 'admin');

				print "Three<br />";

			}
			
			return true;
		}
		catch (Exception $e) {
			ErrorHandler::addError($e->getMessage());
		}
	}
	
	public static function insertDatabase($sDataHost, $sDataBase, $sDataUser, $sDataPass) {
		try {
			$oDatabase = array();
			require('setup/mijob-'.cAppVersion.'.mijobdb');
			DataHandler::connect($sDataHost, $sDataBase, $sDataUser, $sDataPass);

			foreach ($oDatabase as $sTablename => $oFields) {
				$sQueryString = 'CREATE TABLE '.$sTablename.' (';
				$bFirstField = true;
				foreach ($oFields as $sFieldname => $oParams) {
					if (!$bFirstField) {
						$sQueryString .= ', ';
					}
					$sQueryString .= $sFieldname.' '.$oParams['type'];
					if ($oParams['primary_key']) {
						$sQueryString .= ' PRIMARY KEY';
					}
					if (!$oParams['null']) {
						$sQueryString .= ' NOT NULL';
					}
					if ($oParams['default']) {
						$sQueryString .= ' DEFAULT \''.$oParams['default'].'\'';
					}
					if ($oParams['extra']) {
						$sQueryString .= ' '.$oParams['extra'];
					}
					$bFirstField = false;
				}
				$sQueryString .= ')';
				$oQuery = DataHandler::query($sQueryString);
			}
			return true;
		}
		catch (Exception $e) {
			ErrorHandler::addError($e->getMessage());
		}
	}
	
	public static function getTypes() {
		$oAppconfigTypes = array(
			'bAllowPublic' => array(
				'type' => 'bool',
				'caption' => msg('Allow public', true),
			),
			'bFreeUsergroups' => array(
				'type' => 'bool',
				'caption' => msg('Allow everyone to create usergroups', true),
			),
			'bFreeClientlists' => array(
				'type' => 'bool',
				'caption' => msg('Allow everyone to create clientlists', true),
			),
		);
		return $oAppconfigTypes;
	}
	
	public static function setConfig($sVarname, $sVarvalue) {
		try {
			// -1 = Unknown SQL error.
			$oCheckQuery = DataHandler::query("
				SELECT varvalue
				FROM appconfig
				WHERE varname = ?
			", $sVarname);

			if ($oCheckQuery->rowCount() == 0) {
				DataHandler::query("
					INSERT INTO appconfig (
						varname,
						varvalue
					) VALUES (
						?,
						?
					)
				", $sVarname, $sVarvalue);
			}
			else {
				DataHandler::query("
					UPDATE appconfig
					SET varvalue = ?
					WHERE varname = ?
				", $sVarvalue, $sVarname);
			}
			
			unset($GLOBALS['appconfig']);
		}
		catch (Exception $e) {
			ErrorHandler::addError($e->getMessage());
		}
	}
	
	public static function getConfig() {
		try {
			if (is_array(@$GLOBALS['appconfig'])) {
				return $GLOBALS['appconfig'];
			}
			
			$oQuery = DataHandler::query("
				SELECT
					varname,
					varvalue
				FROM appconfig
			");

			$GLOBALS['appconfig'] = array();
			while (list($sVarname, $sVarvalue) = $oQuery->fetch(PDO::FETCH_NUM)) {
				$GLOBALS['appconfig'][$sVarname] = $sVarvalue;
			}
			return $GLOBALS['appconfig'];
		}
		catch (Exception $e) {
			ErrorHandler::addError($e->getMessage());
		}
	}
}
?>
